package dao

import (
	"context"
	"device-admin/internal/dal"
	"device-admin/internal/define"
	"device-admin/internal/models"

	"192.168.1.75/go-pkg/errorx"
)

type LocationTag struct{}

// Exists 是否存在标签
func (LocationTag) Exists(ctx context.Context, query *dal.Query, tagID string) bool {
	lt := query.LocationTag
	count, err := lt.WithContext(ctx).Where(lt.ID.Eq(tagID)).Count()
	if err != nil || count <= 0 {
		return false
	}
	return true
}

// Add 添加位置标签
func (LocationTag) Add(ctx context.Context, query *dal.Query, name, merchantID string) (string, error) {
	if name == "" {
		return "", errorx.New("标签名称不能为空", -1)
	}
	lt := query.LocationTag
	record := models.LocationTag{}
	record.Name = name
	record.MerchantID = merchantID
	err := lt.WithContext(ctx).Create(&record)
	if err != nil {
		return "", errorx.New("添加标签失败", -1)
	}
	return record.ID, nil
}

// Update 更新位置标签
func (LocationTag) Update(ctx context.Context, query *dal.Query, tagID, name, merchantID string) error {
	if tagID == "" {
		return errorx.New("标签ID不能为空", -1)
	}
	if name == "" {
		return errorx.New("标签名称不能为空", -1)
	}
	lt := query.LocationTag
	tx := lt.WithContext(ctx).Where(lt.ID.Eq(tagID))
	if merchantID != "1" {
		tx = tx.Where(lt.MerchantID.In(GetFamilyMerchants(merchantID)...))
	}
	res, err := tx.Update(lt.Name, name)
	if err != nil || res.RowsAffected <= 0 {
		return errorx.New("更新标签失败", -1)
	}
	return nil
}

// Delete 删除位置标签
func (LocationTag) Delete(ctx context.Context, query *dal.Query, tagID, merchantID string) error {
	if tagID == "" {
		return errorx.New("标签ID不能为空", -1)
	}
	lt := query.LocationTag
	tx := lt.WithContext(ctx).Where(lt.ID.Eq(tagID))
	if merchantID != "1" {
		tx = tx.Where(lt.MerchantID.In(GetFamilyMerchants(merchantID)...))
	}
	res, err := tx.Delete(&models.LocationTag{})
	if err != nil || res.RowsAffected <= 0 {
		return errorx.New("删除标签失败", -1)
	}
	return nil
}

// List 位置标签列表
func (LocationTag) List(ctx context.Context, query *dal.Query, tagName, merchantID string, page, limit int) (res []*models.LocationTag, total int64, err error) {
	lt := dal.LocationTag
	tx := lt.WithContext(ctx)
	// 标签名称搜索
	if tagName != "" {
		tx = tx.Where(lt.Name.Like("%" + tagName + "%"))
	}
	// 只能看到直系商户的下的位置标签
	if merchantID != "1" {
		tx = tx.Where(lt.MerchantID.In(GetFamilyMerchants(merchantID)...))
	}
	// 总条数
	total, err = tx.Count()
	if err != nil {
		return nil, 0, err
	}
	// 分页记录
	res, err = tx.Offset(GetPageOffset(page, limit)).
		Limit(GetPageLimit(limit)).
		Find()
	if err != nil {
		return nil, 0, err
	}
	return res, total, nil
}

// 标签位置列表类型
type TagLocationListType struct {
	ID         string `json:"id" gorm:"column:id"`
	Name       string `json:"name" gorm:"column:name"`
	ProvinceID string `json:"-" gorm:"column:province_id"`
	Province   string `json:"province" gorm:"-"`
	CityID     string `json:"-" gorm:"column:city_id"`
	City       string `json:"city" gorm:"-"`
	DistrictID string `json:"-" gorm:"column:district_id"`
	District   string `json:"district" gorm:"-"`
	TotalRobot int    `json:"total_robot" gorm:"column:total_robot"`
}

// LocationList 某个标签下的位置列表
func (LocationTag) LocationList(
	ctx context.Context,
	query *dal.Query,
	tagID, locationName string,
	page, limit int,
) (
	list []*TagLocationListType,
	total int64,
	err error,
) {
	l := query.Location
	oa := query.ObjAssociation
	d := query.Device
	tx := l.WithContext(ctx).
		Join(oa, l.ID.EqCol(oa.ObjID)).
		LeftJoin(d, d.LocationID.EqCol(l.ID)).
		Select(l.ID, l.Name, l.ProvinceID, l.CityID, l.DistrictID, d.ID.Count().As("total_robot")).
		Where(oa.AssociationType.Eq(int(define.AssociationLocationTag))).
		Where(oa.AssociationID.Eq(tagID)).
		Group(l.ID)

	// 位置名称查询
	if locationName != "" {
		tx = tx.Where(l.Name.Like("%" + locationName + "%"))
	}

	total, err = tx.Count()
	if err != nil {
		return nil, 0, err
	}
	err = tx.Offset(GetPageOffset(page, limit)).Limit(GetPageLimit(limit)).Scan(&list)
	if err != nil {
		return nil, 0, err
	}
	if total == 0 {
		list = []*TagLocationListType{}
	}
	return list, total, err
}
